package com.db.collections;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Random;
import java.util.TreeMap;

public class MemoryUsage {
  
  final static int N_ELEMENTS = 1_000_000;
  final Runtime runtime = Runtime.getRuntime();
  final Random random = new Random();
  
  public void runTest() {
    System.out.println("size = " + N_ELEMENTS);
    long memory = 0;
    //Array
    System.gc();
    memory = runtime.totalMemory() - runtime.freeMemory();
    int[] array = new int[N_ELEMENTS];
    for (int i = 0; i < N_ELEMENTS; ++i) {
      array[i] = i;
    }
    System.gc();
    memory = runtime.totalMemory() - runtime.freeMemory() - memory;
    System.out.println("-----------------------");
    System.out.println("Array: " + memory + " bytes");
    
    System.out.println(Arrays.hashCode(array));
    
    //ArrayList
    System.gc();
    memory = runtime.totalMemory() - runtime.freeMemory();
    ArrayList<Integer> arrayList = new ArrayList<>();
    for (int i = 0; i < N_ELEMENTS; ++i) {
      arrayList.add(new Integer(random.nextInt()));
    }
    System.gc();
    memory = runtime.totalMemory() - runtime.freeMemory() - memory;
    System.out.println("-----------------------");
    System.out.println("ArrayList: " + memory + " bytes");
    
    System.out.println(arrayList.hashCode());
    
    //LinkedList
    System.gc();
    memory = runtime.totalMemory() - runtime.freeMemory();
    LinkedList<Integer> linkedList = new LinkedList<>();
    for (int i = 0; i < N_ELEMENTS; ++i) {
      linkedList.add(new Integer(random.nextInt()));
    }
    System.gc();
    memory = runtime.totalMemory() - runtime.freeMemory() - memory;
    System.out.println("-----------------------");
    System.out.println("LinkedList: " + memory + " bytes");
    
    System.out.println(linkedList.hashCode());
    
    //HashMap
    System.gc();
    memory = runtime.totalMemory() - runtime.freeMemory();
    HashMap<Integer, Integer> hashMap = new HashMap<>();
    for (int i = 0; i < N_ELEMENTS; ++i) {
      hashMap.put(new Integer(i), new Integer(random.nextInt()));
    }
    System.gc();
    memory = runtime.totalMemory() - runtime.freeMemory() - memory;
    System.out.println("-----------------------");
    System.out.println("HashMap: " + memory + " bytes");
    
    System.out.println(hashMap.hashCode());
    
    //TreeMap
    System.gc();
    memory = runtime.totalMemory() - runtime.freeMemory();
    TreeMap<Integer, Integer> treeMap = new TreeMap<>();
    for (int i = 0; i < N_ELEMENTS; ++i) {
      treeMap.put(new Integer(i), new Integer(random.nextInt()));
    }
    System.gc();
    memory = runtime.totalMemory() - runtime.freeMemory() - memory;
    System.out.println("-----------------------");
    System.out.println("TreeMap: " + memory + " bytes");
    
    System.out.println(treeMap.hashCode());
    
    //IntHashMap
    System.gc();
    memory = runtime.totalMemory() - runtime.freeMemory();
    IntMap intHashMap = new IntHashMap();
    for (int i = 0; i < N_ELEMENTS; ++i) {
      intHashMap.put(i, random.nextInt());
    }
    System.gc();
    memory = runtime.totalMemory() - runtime.freeMemory() - memory;
    System.out.println("-----------------------");
    System.out.println("IntHashMap: " + memory + " bytes");
    
    System.out.println(intHashMap.hashCode());
  }
  
  public static void main(String[] args) {
    MemoryUsage memoryUsage = new MemoryUsage();
    memoryUsage.runTest();
  }
}

